/**
 * FileContentManager is a Java based file manager desktop application, it can
 * show, edit and manipulate the content of the files archived inside a zip.
 * 
 * Copyright (C) 2007
 * 
 * Created by Camila Sanchez [http://mimix.wordpress.com/], Rafael Naufal
 * [http://rnaufal.livejournal.com] and Rodrigo [rdomartins@gmail.com]
 * 
 * FileContentManager is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as published by the
 * Free Software Foundation; either version 2.1 of the License, or (at your
 * option) any later version.
 * 
 * This library is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
 * details.
 * 
 * You should have received a copy of the GNU Lesser General Public License
 * along with FileContentManager; if not, write to the Free Software Foundation,
 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */
package br.com.jteam.jfcm.gui;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Toolkit;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JSplitPane;

import br.com.jteam.jfcm.controller.Subscriber;
import br.com.jteam.jfcm.controller.event.Event;
import br.com.jteam.jfcm.controller.event.OpenFileEvent;
import br.com.jteam.jfcm.controller.event.OpenHistoryFileEvent;

/**
 * <p>
 * Frame principal da aplica&ccedil;&atilde;o. Extende e customiza um JFrame e
 * tamb&eacute;m &eacute; notificado da ocorr&ecirc;ncia do
 * {@link OpenFileEvent} e {@link OpenHistoryFileEvent} para atualizar o
 * t&iacute;tulo da janela com o seguinte padr&atilde;o:
 * </p>
 * <p>
 * T�TULO [ {CAMINHO_DO_ARQUIVO} ]
 * </p>
 * 
 * @see br.com.jteam.jfcm.controller.event.OpenFileEvent
 * @see br.com.jteam.jfcm.controller.event.OpenHistoryFileEvent
 */
public class MainFrame extends JFrame implements Subscriber
{
	/**
	 * "Folga" entre a &aacute;rea de conte&uacute;do da aplica&ccedil;&atilde;o
	 * e os limites laterais do frame.
	 */
	private final int LACK_PANEL_SIZE = 10;

	/**
	 * Altura m&aacute;xima do frame da aplica&ccedil;&atilde;o. Ser&aacute;
	 * igual a altura da tela subtra&iacute;do de 100 pixels.
	 */
	private final int MAX_HEIGHT;

	/**
	 * Largura m&aacute;xima do frame da aplica&ccedil;&atilde;o. Ser&aacute;
	 * igual a largura da tela subtra&iacute;do de 100 pixels.
	 */
	private final int MAX_WIDTH;

	/**
	 * T&iacute;tulo do frame.
	 */
	private final String TITLE;

	public MainFrame(String title)
	{
		super(title);
		Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
		MAX_WIDTH = screenSize.width - 100;
		MAX_HEIGHT = screenSize.height - 150;
		TITLE = title;
		setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
		setPreferredSize(new Dimension(MAX_WIDTH, MAX_HEIGHT));
		setLocationByPlatform(true);
		setResizable(false);
		configLayout();
	}

	/**
	 * @return O resultado do c&aacute;lcula das dimens&otilde;es da &aacute;rea
	 *         de conte&uacute;do levando em conta as dimens&otilde;es do frame
	 *         e as "folgas" laterais.
	 */
	private Dimension calculateContentPanelDimensions()
	{
		float height = MAX_HEIGHT - 2 * LACK_PANEL_SIZE - 50;
		float width = MAX_WIDTH - 2 * LACK_PANEL_SIZE;
		return new Dimension((int) width, (int) height);
	}

	/**
	 * @return O resultado do c&aacute;lcula das dimens&otilde;es das "folgas"
	 *         laterais.
	 */
	private Dimension calculateLackPanelDimensions()
	{
		float height = LACK_PANEL_SIZE - 5;
		float width = LACK_PANEL_SIZE;
		return new Dimension((int) width, (int) height);
	}

	/**
	 * Enquadra a &aacute;rea vis&iacute;vel da aplica&ccedil;&atilde;o entre
	 * pain&eacute;is que servem como "folgas".
	 */
	private void configLayout()
	{
		setLayout(new BorderLayout());
		Dimension lackDimension = calculateLackPanelDimensions();
		JPanel northLackPanel = new JPanel();
		northLackPanel.setPreferredSize(lackDimension);
		JPanel leftLackPanel = new JPanel();
		leftLackPanel.setPreferredSize(lackDimension);
		JPanel rightLackPanel = new JPanel();
		rightLackPanel.setPreferredSize(lackDimension);
		JPanel southLackPanel = new JPanel();
		southLackPanel.setPreferredSize(lackDimension);
		getContentPane().add(northLackPanel, BorderLayout.NORTH);
		getContentPane().add(leftLackPanel, BorderLayout.LINE_START);
		getContentPane().add(rightLackPanel, BorderLayout.LINE_END);
		getContentPane().add(southLackPanel, BorderLayout.SOUTH);
	}

	public void notify(Event event)
	{
		if (event.getClass().equals(OpenFileEvent.class))
		{
			updateTitle(((OpenFileEvent) event).getPresentationFile().getName());
		} else if (event.getClass().equals(OpenHistoryFileEvent.class))
		{
			updateTitle(((OpenHistoryFileEvent) event)	.getPresentationFile()
														.getName());
		}
	}

	/**
	 * Modifica o conte&uacute;do exibido no centro do frame.
	 * 
	 * @param contentPanel
	 *            Painel com o conte&uacute;do que ser&aacute; exibido no centro
	 *            do frame. N&atilde;o pode ser nulo.
	 * @throws IllegalArgumentException
	 *             Caso o par&acirc;metro seja nulo.
	 */
	public void setContent(JSplitPane contentPanel)
	{
		if (contentPanel == null)
		{
			throw new IllegalArgumentException("Null content panel.");
		}
		contentPanel.setPreferredSize(calculateContentPanelDimensions());
		getContentPane().add(contentPanel, BorderLayout.CENTER);
	}

	/**
	 * Atualiza o t&iacute;tulo da aplica&ccedil;&atilde;o com o nome do arquivo
	 * aberto.
	 * 
	 * @param fileName
	 *            Nome do arquivo aberto.
	 */
	private void updateTitle(String fileName)
	{
		StringBuilder title = new StringBuilder();
		title.append(TITLE);
		title.append(" [ ");
		title.append(fileName);
		title.append(" ] ");
		setTitle(title.toString());
	}
}
